import requests
from urllib.parse import quote
import json
import folium
from geopy.geocoders import Nominatim

# API配置
OPENAI_API_URL = "https://api.gptsapi.net/v1"
OPENAI_API_KEY = "sk-Nnm83576358bafced470371c05725c2e9a8dfb994c4NEhd4"
SERPAPI_API_KEY = "5f2b4bd965b1a6e802ba08af5fa625930a54ee235267426298c2f4cb04ed189a"
OPENWEATHERMAP_API_KEY = "57dbc0b8c073126868e328d089d6db44"

def get_weather_info(lat, lon):
    base_url = "https://api.openweathermap.org/data/2.5/weather"
    params = {"lat": lat, "lon": lon, "appid": OPENWEATHERMAP_API_KEY, "units": "metric"}
    try:
        response = requests.get(base_url, params=params)
        if response.status_code == 200:
            return response.json()
        return None
    except requests.RequestException:
        return None

def fetch_serpapi_results(query):
    encoded_query = quote(query)
    url = f"https://serpapi.com/search.json?engine=google&q={encoded_query}&api_key={SERPAPI_API_KEY}"
    try:
        response = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}, timeout=10)
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException:
        return None

def send_to_openai(location_info, weather_info, search_query, search_results):
    try:
        search_summary = []
        if search_results and 'organic_results' in search_results:
            for result in search_results['organic_results'][:5]:
                search_summary.append(f"   - {result['title']}")
        
        prompt = f"""
        请根据以下信息生成推荐内容：
        1. 位置：{location_info.get('city', '未知城市')}, {location_info.get('country_name', '未知国家')}
        2. 天气：{weather_info['weather'][0]['description']}，温度 {weather_info['main']['temp']}°C，湿度 {weather_info['main']['humidity']}%
        3. 用户搜索内容：{search_query}
        4. 你可以参考的推荐摘要如下：
        {chr(10).join(search_summary) if search_summary else '   - 无有效搜索结果'}
        
        要求：
        - 返回一个JSON格式的响应，包含"text"和"locations"两个字段
        - "text"字段包含给用户看的推荐文本
        - "locations"字段是一个数组，每个元素包含"name"、"description"、"latitude"和"longitude"
        - 优先考虑带有经纬度坐标信息的推荐项目
        - 如果没有坐标信息，请尽量提供详细地址
        """
        
        payload = {
            "model": "gpt-4o-mini",
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.7,
            "response_format": {"type": "json_object"}
        }

        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {OPENAI_API_KEY}"
        }

        response = requests.post(OPENAI_API_URL + "/chat/completions", json=payload, headers=headers)
        response.raise_for_status()
        return response.json()["choices"][0]["message"]["content"]
    except Exception as e:
        print(f"OpenAI请求错误: {str(e)}")
        return None

def generate_recommendation_map(user_location, recommendation_data):
    """
    根据推荐数据生成交互式地图
    :param user_location: 用户位置字典，包含latitude和longitude
    :param recommendation_data: 推荐数据字典，包含locations数组
    :return: 生成的HTML文件名，失败返回None
    """
    try:
        # 创建地图
        m = folium.Map(location=[user_location['latitude'], user_location['longitude']], zoom_start=12)
        
        # 添加用户位置标记
        folium.Marker(
            [user_location['latitude'], user_location['longitude']],
            popup=f"Your Location<br>{user_location.get('city', 'Unknown')}",
            icon=folium.Icon(color="blue")
        ).add_to(m)
        
        # 添加推荐地点标记（如果有）
        if 'locations' in recommendation_data:
            for idx, place in enumerate(recommendation_data['locations']):
                folium.Marker(
                    [place['latitude'], place['longitude']],
                    popup=f"<b>{place['name']}</b><br>{place['description']}",
                    icon=folium.Icon(color="red")
                ).add_to(m)
        
        # 保存地图
        filename = "recommendation_map.html"
        m.save(filename)
        print(f"推荐地图已生成: {filename}")
        return filename
    except Exception as e:
        print(f"生成地图时出错: {str(e)}")
        return None
    
def recommend():
    # 模拟请求数据
    data = {"query": "sport events"}
    
    # 获取位置信息
    try:
        location_resp = requests.get('https://freegeoip.app/json/')
        location = location_resp.json()
    except Exception as e:
        print(f"无法获取位置信息: {str(e)}")
        return
    
    # 获取天气信息
    weather = get_weather_info(location['latitude'], location['longitude'])
    if not weather:
        print("无法获取天气信息")
        return
    
    # 获取搜索结果
    search_results = fetch_serpapi_results(data['query'])
    if not search_results:
        print("无法获取搜索结果")
        return
    
    # 获取AI推荐
    recommendation = send_to_openai(location, weather, data['query'], search_results)
    if not recommendation:
        print("无法生成推荐")
        return
    
    print("推荐结果:")
    print(json.dumps({
        "data": json.loads(recommendation),
        "user_location": {
            "lat": location['latitude'],
            "lng": location['longitude']
        }
    }, indent=2))

    try:
        # 解析推荐数据
        rec_data = json.loads(recommendation)
        # 检查推荐数据格式
        if isinstance(rec_data, dict):
            # 如果推荐数据本身就是字典格式，直接使用
            generate_recommendation_map(location, rec_data)
        else:
            # 如果推荐数据不是字典格式，包装成标准格式
            generate_recommendation_map(location, {"text": str(rec_data), "locations": []})
    except Exception as e:
        print(f"处理推荐数据时出错: {str(e)}")

if __name__ == '__main__':
    recommend()